package main

import (
	"bufio"
	"endow/cfg"
	"endow/img"
	"fmt"
	"log"
	"os"
	"sort"
	"sync"
)

type LogFile struct {
	File   *os.File
	Logger *log.Logger
}

type MultiLogFile map[string]LogFile

var (
	appCfg cfg.Config
)

func init() {
	appCfg = cfg.NewConfig()
}

func main() {
	var (
		urlList   []string
		itemCount int
		err       error
		fileLog   *os.File
		wg        sync.WaitGroup
		multiLog  MultiLogFile = make(MultiLogFile)
		mLKeys    []string
	)
	urlList, itemCount, err = appCfg.GetURLList()

	if err != nil {
		log.Fatalf("Ошибка при открытии файла '%s': %v", appCfg.FileUrls, err)
	}

	fileLog, err = appCfg.Logging()
	if err != nil {
		log.Fatalf("Ошибка при создании лог-файла: %v", err)
	}

	for _, item := range cfg.GenerateLogFileNames(itemCount, appCfg.LogFile) {
		file, err := os.Create(item)
		if err != nil {
			log.Fatalf("Ошибка при создании '%s': %v", item, err)
		}
		logger := log.New(file, "", log.Lmsgprefix)
		multiLog[item] = LogFile{File: file, Logger: logger}
	}

	for k := range multiLog {
		mLKeys = append(mLKeys, k)
	}

	sort.Strings(mLKeys)

	log.Printf(
		"[Операции редактирования]\n\tКонвертация: %v\n\tОбрезка: %v\n\tМасштабирование: %v\n\tХолст квадраный: %v\n\tПерезапись файлов: %v\n\n",
		appCfg.Convert, appCfg.Crop, appCfg.Scale, appCfg.Square, appCfg.Override,
	)

	ind := 0
	for _, item := range mLKeys {
		wg.Add(1)
		link := urlList[ind]
		go run(ind, link, &wg, multiLog[item].Logger)
		ind++
	}

	wg.Wait()
	fileLog.Close()

	for _, item := range multiLog {
		item.File.Close()
	}

	for _, item := range mLKeys {
		file, err := os.Open(item)
		if err != nil {
			log.Fatalf("Ошибка при открытии '%s': %v\n", item, err)
		}
		defer file.Close()

		lFile, err := os.OpenFile(appCfg.LogFile, os.O_APPEND|os.O_WRONLY, 0600)
		if err != nil {
			log.Fatalf("Ошибка при открытии '%s': %v\n", item, err)
		}
		defer lFile.Close()

		buf := bufio.NewScanner(file)

		for buf.Scan() {
			lFile.WriteString(buf.Text() + "\n")
		}
	}

	for i := range multiLog {
		os.Remove(i)
	}
}

func isFileLocal(url string) bool {
	_, err := os.Stat(url)

	if err != nil {
		return false
	} else {
		return true
	}
}

func run(i int, item string, w *sync.WaitGroup, myLog *log.Logger) (err error) {
	defer w.Done()
	currentItemCount := i + 1
	pic := img.NewImg(item, appCfg.Path, appCfg.Name, currentItemCount, myLog)

	myLog.Printf("[Картинка № %d]\n\tПолное имя: %s\n\tСсылка: %s\n\n", currentItemCount, pic.FullPath, pic.Link)

	if isFileLocal(item) {
		myLog.Println("Link leads to local file")
		err = pic.LocalCopyImage(appCfg.Override)
	} else {
		myLog.Println("Link leads to external file")
		err = pic.DownloadImage(appCfg.Override)
	}

	if err != nil {
		myLog.Print(err)
		return
	}

	myLog.Printf("Расширение: %s\n", pic.Extension)

	if appCfg.Convert {
		err = pic.ConvertToJPEG(appCfg.Override)
	}

	if appCfg.Crop {
		pic.TrimImage()
	}

	if appCfg.Scale {
		pic.Scale()
	}

	if appCfg.Square {
		pic.MakeSquare()
	}

	myLog.Println()

	fmt.Println(pic.FullPath, "готов")
	return
}
